#Область ОбработчикиСобытийФормы

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	
	КопироватьДанныеФормы(Параметры.Объект, Объект);
	
	Обработка = РеквизитФормыВЗначение("Объект");
	
	Заголовок = Параметры.Заголовок + " (таблица значений)";
	
	Если Параметры.Значение = Неопределено Тогда
		Таблица = Новый ТаблицаЗначений;
	Иначе
		Таблица = Обработка.СтрокаВЗначение(Параметры.Значение.Значение);
	КонецЕсли;
	
	ЗаполнитьТаблицуЗначений(Таблица);
	
	фТолькоПросмотр = Ложь;
	Если Параметры.Свойство("ТолькоПросмотр", фТолькоПросмотр) И фТолькоПросмотр = Истина Тогда
		Элементы.ТаблицаЗначений.ТолькоПросмотр = Истина;
		Элементы.КнопкаОК.Видимость = Ложь;
	КонецЕсли;

	СуффиксРеквизитаКонтейнера=Обработка.СуффиксРеквизитаКонтейнера();
КонецПроцедуры

#КонецОбласти

#Область ОбработчикиСобытийЭлементовТаблицыФормыТаблицаЗначений

//@skip-warning
&НаКлиенте
Процедура ПолеТаблицыНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
	Перем Контейнер;
	
	ИмяКолонки = ТаблицаЗначенийСоответствиеКолонок[Элемент.Имя];
	ИмяКолонкиКонтейнера = ИмяКолонки + СуффиксРеквизитаКонтейнера;
	
	Если ТаблицаЗначенийКолонкиКонтейнера.Свойство(ИмяКолонки) Тогда
		
		СтрокаТаблицы = ТаблицаЗначений.НайтиПоИдентификатору(Элементы.ТаблицаЗначений.ТекущаяСтрока);
		Контейнер = СтрокаТаблицы[ИмяКолонкиКонтейнера];
		
		Если НЕ ЗначениеЗаполнено(Контейнер) Тогда
			ИнициализироватьКонтейнерыСтрокиПоТипам(Элементы.ТаблицаЗначений.ТекущаяСтрока, ТаблицаЗначенийКолонкиКонтейнера);
			Контейнер = СтрокаТаблицы[ИмяКолонкиКонтейнера];
		КонецЕсли;
		
		Если ЗначениеЗаполнено(Контейнер.Тип) Тогда
			
			Если Контейнер.Тип = "Тип" Тогда
				СтандартнаяОбработка = Ложь;
				ПараметрыОповещения = Новый Структура("Таблица, Строка, Поле", "ТаблицаЗначений", Элементы.ТаблицаЗначений.ТекущаяСтрока, ИмяКолонки);
				ОписаниеОповещенияОЗакрытииОткрываемойФормы = Новый ОписаниеОповещения("ОкончаниеРедактированияСтроки", ЭтаФорма, ПараметрыОповещения);
				ПараметрыОткрытия = Новый Структура("Объект, ТипЗначения", Объект, Контейнер);
				ОткрытьФорму(ПолноеИмяФормы("РедактированиеТипа"), ПараметрыОткрытия, ЭтаФорма, Истина, , , ОписаниеОповещенияОЗакрытииОткрываемойФормы, РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);
			ИначеЕсли Контейнер.Тип = "МоментВремени" Тогда
				СтандартнаяОбработка = Ложь;
				ПараметрыОповещения = Новый Структура("Таблица, Строка, Поле", "ТаблицаЗначений", Элементы.ТаблицаЗначений.ТекущаяСтрока, ИмяКолонки);
				ОписаниеОповещенияОЗакрытииОткрываемойФормы = Новый ОписаниеОповещения("ОкончаниеРедактированияСтроки", ЭтаФорма, ПараметрыОповещения);
				ПараметрыОткрытия = Новый Структура("Объект, Значение", Объект, Контейнер);
				ОткрытьФорму(ПолноеИмяФормы("РедактированиеГраницыМомента"), ПараметрыОткрытия, ЭтаФорма, Ложь, , , ОписаниеОповещенияОЗакрытииОткрываемойФормы, РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);
			КонецЕсли;
			
		КонецЕсли;
		
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ОкончаниеРедактированияСтроки(РезультатЗакрытия, ДополнительныеПараметры) Экспорт
	
	Если РезультатЗакрытия <> Неопределено Тогда
		
		чИдентификаторСтроки = ДополнительныеПараметры.Строка;
		Значение = Неопределено;
		Если РезультатЗакрытия.Свойство("Значение", Значение) Тогда
			ТаблицаЗначений[чИдентификаторСтроки][ДополнительныеПараметры.Поле + СуффиксРеквизитаКонтейнера] = Значение;
			ТаблицаЗначений[чИдентификаторСтроки][ДополнительныеПараметры.Поле] = Значение.Представление;
		Иначе
			ТаблицаЗначений[чИдентификаторСтроки][ДополнительныеПараметры.Поле + СуффиксРеквизитаКонтейнера] = РезультатЗакрытия.ОписаниеКонтейнера;
			ТаблицаЗначений[чИдентификаторСтроки][ДополнительныеПараметры.Поле] = РезультатЗакрытия.ОписаниеКонтейнера.Представление;
		КонецЕсли;
		
	КонецЕсли;
	
КонецПроцедуры
#КонецОбласти

#Область ОбработчикиКомандФормы

&НаКлиенте
Процедура КомандаОчистить(Команда)
	ТаблицаЗначений.Очистить();
КонецПроцедуры

&НаКлиенте
Процедура КомандаОК(Команда)
	ВозвращаемоеЗначение = Новый Структура("Значение", ПолучитьВозвращаемуюТаблицу());
	Закрыть(ВозвращаемоеЗначение);
КонецПроцедуры

&НаКлиенте
Процедура КомандаЗаполнитьИзСтрокиВнутр(Команда)
	
	ОписаниеОповещения = Новый ОписаниеОповещения("ВводЗначениеИзСтрокиВнутрЗавершение", ЭтотОбъект);
	Подсказка = НСтр("ru = 'Введите системное представление значения в строковом виде.'");
	ПоказатьВводСтроки(ОписаниеОповещения, , Подсказка, , Истина);

КонецПроцедуры

&НаКлиенте
Процедура КомандаЗначениеИзФайла(Команда)
	
	#Если Не ВебКлиент Тогда

		ИмпортироватьЗначениеИзФайла();

	#КонецЕсли
	
КонецПроцедуры

&НаКлиенте
Процедура КомандаЗначениеВФайл(Команда)
	
	#Если Не ВебКлиент Тогда

	ЭкспортироватьЗначениеВФайл();

	#КонецЕсли
	
КонецПроцедуры

&НаКлиенте
Процедура КомандаЗначениеВСтрокуВнутр(Команда)
	
	Подсказка = НСтр("ru = 'Системное строковое представление переданного значения.'");
	ПоказатьВводСтроки(Новый ОписаниеОповещения(), СериализованноеЗначение(), Подсказка, , Истина);

КонецПроцедуры

#КонецОбласти

#Область СлужебныеПроцедурыИФункции

&НаСервере
Функция ПолучитьВозвращаемуюТаблицу()
	Обработка = РеквизитФормыВЗначение("Объект");
	тзВозвращаемаяТаблица = Обработка.ТаблицаИзРеквизитовФормы(ТаблицаЗначений, ТаблицаЗначенийКолонкиКонтейнера);
	Возврат Обработка.Контейнер_СохранитьЗначение(тзВозвращаемаяТаблица);
КонецФункции

&НаСервере
Процедура ИнициализироватьКонтейнерыСтрокиПоТипам(Знач чСтрока, Знач ТаблицаЗначенийКолонкиКонтейнера)
	РеквизитФормыВЗначение("Объект").ИнициализироватьКонтейнерыСтрокиПоТипам(
		ТаблицаЗначений.НайтиПоИдентификатору(чСтрока),
		ТаблицаЗначенийКолонкиКонтейнера);
КонецПроцедуры

&НаКлиенте
Функция ПолноеИмяФормы(ИмяФормы)
	Возврат СтрШаблон("%1.Форма.%2", Объект.ПутьМетаданных, ИмяФормы);
КонецФункции

&НаКлиенте
Процедура ВводЗначениеИзСтрокиВнутрЗавершение(Результат, ДополнительныеПараметры) Экспорт

	Если ЗначениеЗаполнено(Результат) Тогда
		Структура = ПараметрыСериализуемыхЗначений();
		Структура.ИзСтроки = Результат;
		ОбработатьСериализуемыеЗначения(Структура);
	КонецЕсли;
	
КонецПроцедуры

// Параметры:
//  Структура - Структура - Структура:
// * ИзСтроки 
// * ИзФайла
//@skip-warning
&НаСервере
Процедура ОбработатьСериализуемыеЗначения(Знач Структура)

	Попытка

		Если Не ПустаяСтрока(Структура.ИзФайла) Тогда
			Значение = ЗначениеИзФайла(Структура.ИзФайла);
		Иначе
			Значение = ЗначениеИзСтрокиВнутр(Структура.ИзСтроки);
		КонецЕсли;

	Исключение
		ВызватьИсключение ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
	КонецПопытки;
	
	Если Не ТипЗнч(Значение) = Тип("ТаблицаЗначений") Тогда
		ТекстОшибки = СтрШаблон(
			НСтр("ru = 'Полученный тип %1. Ожидается ""ТаблицаЗначений""'"), 
			ТипЗнч(Значение));
		УИ_ОбщегоНазначенияКлиентСервер.СообщитьПользователю(ТекстОшибки);
		Возврат;
	КонецЕсли;
	
	ЗаполнитьТаблицуЗначений(Значение);
	 
КонецПроцедуры

&НаСервере
Процедура ЗаполнитьТаблицуЗначений(Значение)
	
	Обработка = РеквизитФормыВЗначение("Объект");
	
	Обработка.СоздатьРеквизитыТаблицыПоКолонкам(
		ЭтотОбъект,
		"ТаблицаЗначений",
		"ТаблицаЗначенийСоответствиеКолонок",
		"ТаблицаЗначенийКолонкиКонтейнера",
		Значение.Колонки,
		Истина);

	Обработка.ТаблицаВРеквизитыФормы(
		Значение, 
		ТаблицаЗначений,
		ТаблицаЗначенийКолонкиКонтейнера);
		
КонецПроцедуры

// Сериализованное значение.
// 
// Возвращаемое значение:
//  Строка - Сериализованное значение таблица значений
//@skip-warning
&НаСервере
Функция СериализованноеЗначение()
	
	Возврат ЗначениеВСтрокуВнутр(ТаблицаЗначений.Выгрузить());
	
КонецФункции

&НаКлиенте
Процедура ИмпортироватьЗначениеИзФайла()
	
	ДиалогВыбораФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
	
	ДиалогВыбораФайла.Фильтр                      = НСтр("ru = 'Файлы (*.txt)|*.txt'");
	ДиалогВыбораФайла.Расширение                  = "txt";
	ДиалогВыбораФайла.Заголовок                   = НСтр("ru = 'Выберите файл'");
	ДиалогВыбораФайла.МножественныйВыбор          = Ложь;
	ДиалогВыбораФайла.ПроверятьСуществованиеФайла = Истина;
		
	ДополнительныеПараметры = Новый Структура;
	ОписаниеОповещенияПослеВыбора = Новый ОписаниеОповещения(
		"ИмпортироватьЗначениеИзФайлаЗавершение",
		ЭтотОбъект,
		ДополнительныеПараметры);

	ДиалогВыбораФайла.Показать(ОписаниеОповещенияПослеВыбора);

КонецПроцедуры

&НаКлиенте
Процедура ИмпортироватьЗначениеИзФайлаЗавершение(ВыбранныйФайл, ДополнительныеПараметры) Экспорт
	
	Если ВыбранныйФайл <> Неопределено Тогда
		Структура = ПараметрыСериализуемыхЗначений();
		Структура.ИзФайла = ВыбранныйФайл[0];
		ОбработатьСериализуемыеЗначения(Структура);
	КонецЕсли;

КонецПроцедуры

// 
// Возвращаемое значение:
//  Структура - Параметры сериализуемых значений:
// * ИзСтроки 
// * ИзФайла
//@skip-warning
&НаКлиенте
Функция ПараметрыСериализуемыхЗначений()
	
	Структура = Новый Структура;
	Структура.Вставить("ИзСтроки");
	Структура.Вставить("ИзФайла");
	
	Возврат Структура;
	
КонецФункции

&НаКлиенте
Процедура ЭкспортироватьЗначениеВФайл()
	
	ДиалогВыбораФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Сохранение);
	
	ДиалогВыбораФайла.Фильтр                      = НСтр("ru = 'Файлы (*.txt)|*.txt'");
	ДиалогВыбораФайла.Расширение                  = "txt";
	ДиалогВыбораФайла.Заголовок                   = НСтр("ru = 'Укажите имя файла'");
	ДиалогВыбораФайла.МножественныйВыбор          = Ложь;
	
	ДополнительныеПараметры = Новый Структура("АдресФайлаНаСервере", ЭкспортироватьЗначениеВФайлСервер());
		
	ОписаниеОповещенияПослеВыбора = Новый ОписаниеОповещения(
		"ЭкспортироватьЗначениеВФайлЗавершение",
		ЭтотОбъект,
		ДополнительныеПараметры);

	ДиалогВыбораФайла.Показать(ОписаниеОповещенияПослеВыбора);

КонецПроцедуры

&НаСервере
Функция ЭкспортироватьЗначениеВФайлСервер()
	
	АдресФайла = "";

	ИмяВременногоФайла = ПолучитьИмяВременногоФайла("txt");
	СохранениеВыполнено = ЗначениеВФайл(ИмяВременногоФайла, ТаблицаЗначений.Выгрузить());
	
	Если СохранениеВыполнено Тогда
		
		ДвоичныеДанные = Новый ДвоичныеДанные(ИмяВременногоФайла);
		АдресФайла = ПоместитьВоВременноеХранилище(ДвоичныеДанные, Новый УникальныйИдентификатор);
		УдалитьФайлы(ИмяВременногоФайла);
		
	КонецЕсли;
	
	Возврат АдресФайла;

КонецФункции

&НаКлиенте
Процедура ЭкспортироватьЗначениеВФайлЗавершение(ВыбранныйФайл, ДополнительныеПараметры) Экспорт

	Если ВыбранныйФайл <> Неопределено Тогда

		ДвоичныеДанные = ПолучитьИзВременногоХранилища(ДополнительныеПараметры.АдресФайлаНаСервере);
		ДвоичныеДанные.Записать(ВыбранныйФайл[0]);

	КонецЕсли;

КонецПроцедуры

#КонецОбласти
